#include "ModuleGPUSURF.h"

////////////////////////////////////////////////////////////////////////////////
void ModuleGPUSURF::init(QCVModuleHandlerInterface * parent)
{
  this->parent=parent;
  
  win=new QWidget();
  layout=new QVBoxLayout(win);


	sb_hessianThreshold=new QDoubleSpinBox(win);
	sb_hessianThreshold->setPrefix("hessianThreshold=");
  sb_nOctaves=new QSpinBox(win);
	sb_nOctaves->setPrefix("nOctaves=");
	sb_nOctaveLayers=new QSpinBox(win);
	sb_nOctaveLayers->setPrefix("nOctaveLayers=");
	cb_extended=new QCheckBox("extended=",win);
	sb_keypointsRatio=new QDoubleSpinBox(win);
	sb_keypointsRatio->setPrefix("keypointsRatio=");

	sb_hessianThreshold->setValue(0.1);
	sb_nOctaves->setValue(4);
	sb_nOctaveLayers->setValue(4);
	cb_extended->setChecked(true);
	sb_keypointsRatio->setValue(0.01);

	layout->addWidget(sb_hessianThreshold);
	layout->addWidget(sb_nOctaves);
	layout->addWidget(sb_nOctaveLayers);
	layout->addWidget(cb_extended);
	layout->addWidget(sb_keypointsRatio);
}
////////////////////////////////////////////////////////////////////////////////
void ModuleGPUSURF::free()
{
  delete win;
}
////////////////////////////////////////////////////////////////////////////////
QString ModuleGPUSURF::getParams()
{
  return tr("");
}
////////////////////////////////////////////////////////////////////////////////
bool ModuleGPUSURF::setParams(QString params)
{
  
		return true;

}

QCVModuleInterface * ModuleGPUSURF::clone()
{
	return new ModuleGPUSURF;
}

//////////////////////////////////////////////////////////////////////////////// 
cv::Mat & ModuleGPUSURF::process()
{
	if(!img.empty())
	{
		//Transfert CPU-->GPU
		cv::gpu::GpuMat gpuImg(img);
		cv::gpu::GpuMat gpuMask(img.rows,img.cols,CV_8UC1);
		gpuMask.setTo(255);
		cv::gpu::GpuMat gpuKeysPoints;

		cv::gpu::SURF_GPU surf_gpu(sb_hessianThreshold->value(), //seuil du hessien
															 sb_nOctaves->value(),//n octaves
															 sb_nOctaveLayers->value(),//nOctaveLayers
                               cb_extended->isChecked(),
															 sb_keypointsRatio->value()
															);//Feature ration

		//Initialisation des paramètres:
	
		/*surf_gpu.threshold=sb_threshold->value();
		surf_gpu.nOctaves=sb_nOctaves->value();
		surf_gpu.nIntervals=sb_nIntervals->value();
		surf_gpu.initialScale=sb_initialScale->value();		
		surf_gpu.edgeScale=sb_edgeScale->value();*/		

		//Récupération des points clefs

		surf_gpu(gpuImg,gpuMask,gpuKeysPoints);

		//Transfert GPU-->CPU
		surf_gpu.downloadKeypoints(gpuKeysPoints,surfKeys_vec);

		surfKeys.create(surfKeys_vec.size(),7);
    for(unsigned int i=0;i<surfKeys_vec.size();i++)
    {
      surfKeys(i,0)=surfKeys_vec[i].pt.x;
      surfKeys(i,1)=surfKeys_vec[i].pt.y;
      surfKeys(i,2)=surfKeys_vec[i].size;
      surfKeys(i,3)=surfKeys_vec[i].angle;
      surfKeys(i,4)=surfKeys_vec[i].response;
			surfKeys(i,5)=surfKeys_vec[i].octave;//octave			
			surfKeys(i,6)=surfKeys_vec[i].class_id;//label
    }
	}
	return surfKeys;
}
////////////////////////////////////////////////////////////////////////////////
void ModuleGPUSURF::setInput(int n,const cv::Mat & m)
{
  if(n==0)
	{
		img.create(m.rows,m.cols,CV_8UC1);
		cvtColor(m, img, CV_RGB2GRAY);
	}
	else if(n==1)
	{
	
	}
}
////////////////////////////////////////////////////////////////////////////////
QWidget* ModuleGPUSURF::widget()
{
  return win;
}
////////////////////////////////////////////////////////////////////////////////
QString ModuleGPUSURF::getName()
{
  return trUtf8("GPU SURF");
}
////////////////////////////////////////////////////////////////////////////////
int ModuleGPUSURF::nbInputs()
{
  return 1;
}
////////////////////////////////////////////////////////////////////////////////
QString ModuleGPUSURF::help(int id)
{
	if(id==-2)
	{
		 return tr("Module d'extraction d'invarients d'echelle.");
	}	
	else if(id==-1)
	{
			return tr("keyspoints");
	}
	else if(id==0)
	{
		return tr("image");
	}
	else 
	{
		return tr("erreur");
	}
}
///////////////////////////////////////////////
Q_EXPORT_PLUGIN2(ModuleGPUSURF_plugin,ModuleGPUSURF);                                                                               
